package com.zzyl.framework.interceptor;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author robin
 * @date 25.5.26 17:49
 */
@Component
@Slf4j
public class MemberInterceptor implements HandlerInterceptor {
    @Autowired
    private TokenService tokenService;
    
    /**
     * 在Controller类请求方法执行之前会执行这里的preHandle方法
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  chosen handler to execute, for type and/or instance evaluation
     * @return true就会放行，false就不会放行
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {
        log.info("拦截器中线程==>{}",Thread.currentThread()
                                           .getId());
        // 一、失败校验：携带的token
        // 如果校验为空
        String token=request.getHeader("authorization");
        if (StrUtil.isBlank(token)) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            return false;
        }
        // 解析token结果为空
        Claims claims=tokenService.parseToken(token);
        if (ObjectUtil.isNull(claims)) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            return false;
        }
        // 解析token获取userId为空
        Object userId=claims.get("userId");
        if (ObjectUtil.isNull(userId)) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            return false;
        }
        // 二、校验成功之后：将获取的用户信息存储
        UserThreadLocal.setValue(Long.valueOf(userId.toString()));
        return true;
    }
    
    /**
     * Controller方法最后都执行完之后最终要做某件事情，可以在这个方法中定义
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  the handler (or {@link HandlerMethod}) that started asynchronous
     *                 execution, for type and/or instance examination
     * @param ex       any exception thrown on handler execution, if any; this does not
     *                 include exceptions that have been handled through an exception resolver
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {
        // TODO : 将来可以在这里清除ThreadLocal中内存，防止内存泄漏
        UserThreadLocal.clean();
    }
}
